package com.study.minio.service.impl;

import com.study.minio.config.GeneralConfig;
import com.study.minio.dao.model.OpenEmptyCardOrder;
import com.study.minio.repository.OpenEmptyCardOrderRepository;
import com.study.minio.service.OpenEmptyCardOrderService;
import com.study.minio.utils.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

@Slf4j
@Service
public class OpenEmptyCardOrderServiceImpl implements OpenEmptyCardOrderService {


    @Autowired
    private GeneralConfig generalConfig;

    @Autowired
    private OpenEmptyCardOrderRepository openEmptyCardOrderRepository;


    @Override
    public void process() {
        String sqlFilePath = generalConfig.getSqlFilePath();
        String sysOrderIdFilePath = generalConfig.getSysOrderIdFilePath();
        try {
            log.info("读取文件{}",sqlFilePath);
            List<String> sqlList = readFile(sqlFilePath);
            log.info("读取文件{}",sysOrderIdFilePath);
            List<String> sysOrderIdList = readFile(sysOrderIdFilePath);
            log.info("初始化数据库连接开始");
            Connection conn = getConnection();
            log.info("初始化数据库连接完成");


            long curTime = System.currentTimeMillis();
            log.info("SQL开始执行{},{}",curTime, DateUtils.format(curTime,"yyyy-MM-dd HH:mm:ss"));
            curTime = System.currentTimeMillis();
            openEmptyCardOrderRepository.insertSql(sqlList);
            log.info("SQL执行完成{},{}",curTime, DateUtils.format(curTime,"yyyy-MM-dd HH:mm:ss"));

            processQuery(sysOrderIdList,conn);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("执行失败"+sqlFilePath,e.getMessage());
        }
        log.info("执行结束");
    }

    private void processQuery(List<String> sysOrderIdList,Connection conn) {
        long curTime;
        for(String sysOrderId: sysOrderIdList){
            processQuery(sysOrderId,conn);
            curTime = System.currentTimeMillis();
            log.info("获取到结果sysOrderId={},{},{}",sysOrderId,curTime, DateUtils.format(curTime,"yyyy-MM-dd HH:mm:ss"));
        }
    }


    private OpenEmptyCardOrder processQuery(String sysOrderId,Connection conn) {
        OpenEmptyCardOrder openEmptyCardOrder = null;
        do {
            Optional<OpenEmptyCardOrder> orderOpt = getOrder(sysOrderId,conn);
            if (!orderOpt.isPresent()) {
                LockSupport.parkNanos(TimeUnit.SECONDS.toSeconds(1));
                continue;
            }
            openEmptyCardOrder = orderOpt.get();
        }while (Objects.isNull(openEmptyCardOrder));
        return openEmptyCardOrder;
    }



    private List<String> readFile(String path) throws IOException {
        List<String> list = new ArrayList<>(204800);
        // 这里rw看你了。要是之都就只写r
        try(RandomAccessFile br = new RandomAccessFile(path, "rw");) {
            String line = null, app = null;
            while ((line = br.readLine()) != null) {
                if(Objects.isNull(line) || line.trim().length() == 0){
                    continue;
                }
                list.add(line);
            }
            br.close();
            return list;
        }
    }


    private Connection getConnection() throws SQLException {
        String url = generalConfig.getUrl();
        String username = generalConfig.getUserName();
        String password = generalConfig.getPassword();
        return DriverManager.getConnection(url, username, password);
    }

    private Optional<OpenEmptyCardOrder> getOrder(String sysOrderId,Connection conn) {
        String sql = "select id,sys_order_id,transaction_id from tb_openemptycard_order where sys_order_id='"+sysOrderId+"' limit 1";
        try (PreparedStatement pst = conn.prepareStatement(sql);
             ResultSet rs = pst.executeQuery(sql);){
            if(rs != null && rs.next()){
                OpenEmptyCardOrder order = new OpenEmptyCardOrder();
                order.setId(rs.getLong("id"));
                order.setSysOrderId(sysOrderId);
                order.setTransactionId(rs.getString("transaction_id"));
                return Optional.ofNullable(order);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            log.error(e.getMessage(),e);
        }

        return Optional.empty();
    }
}
